
import { IO } from "../common/io.js";
import * as DOM from "../functions/dom/domtool.js";
import { Color32 } from "../functions/image/color.js";
import { ImgTool } from "../functions/image/image.js";
import { tt_impl } from "../functions/ttapi_impl_web/ttimpl_web.js";
import { tt } from "../functions/ttapi_interface/ttapi.js";
import * as tt2 from "../functions/ttapi_layer2/ttlayer2.js";

export async function Tool_AniPreviewerInit() {
    __initDom();

    let impl = new tt_impl.ttimpl_browser();
    impl.Init(_canvas.getHtml());
    //换掉ttloader 这里的加载器和正式环境不同
    tt.loader = new EditorLoader();
    tt.graphic.OnRender = () => {
        if (player != null) {
            batcher.BeginDraw(tt.graphic.getMainScreen());
            player.RenderCenter(batcher, tt.Color.White);
            player.Render(batcher);
            batcher.EndDraw();
        }
    }
    tt.graphic.OnUpdate = (delta: number) => {
        if (player != null) {
            player.Update(_play ? delta : 0)
        }
    }
    tt.graphic.getMainScreen().ClearColor = new tt.Color(0, 0, 0, 1);
    batcher = tt.graphic.CreateRenderer_Batcher();


    await __InitPlayer();
}

//由于编辑器环境的加载器和web环境不同，要替换掉
class EditorLoader implements tt.ILoader {
    async LoadStringAsync(name: string): Promise<string> {
        return await IO.LoadTextFile(name);
    }
    async LoadBinaryAsync(name: string): Promise<ArrayBuffer> {
        return await IO.LoadBinaryFile(name);
    }
    async LoadImageAsync(name: string): Promise<HTMLImageElement> {
        let bin = await this.LoadBinaryAsync(name);
        return await ImgTool.Bin2ImgAsync(new Uint8Array(bin));
    }
    async LoadImageDataAsync(name: string, gray: boolean): Promise<tt.ImageBuffer> {
        let bin = await this.LoadBinaryAsync(name);
        let data = await ImgTool.Bin2ImgDataAsync(new Uint8Array(bin));
        let buf = new tt.ImageBuffer();
        buf.gray = false;
        buf.data = data.data as any as Uint8Array;
        buf.width = data.width;
        buf.height = data.height;
        return buf;
    }
}



var _canvas: DOM.CanvasRaw;
var _debugpanel: DOM.Panel;
var _anipanel: DOM.Panel;
var _infopanel: DOM.Panel;
var _dirpanel: DOM.Panel;
var _framepanel: DOM.Panel;
function __initDom() {
    DOM.DomTool.InitFullScreen();



    let sall = DOM.DomTool.AddSpliter();
    sall.Style_Fill();
    sall.SetSplitPosBottom(300);

    let s1 = new DOM.Splitter();
    s1.Style_Fill();
    s1.SetSplitPosLeft(200);
    sall._panel1.AddChild(s1);

    //底栏
    let sbot = new DOM.Splitter();
    sbot.Style_Fill();
    sbot.SetSplitPosRight(400);

    sall._panel2.AddChild(sbot);
    //左竖边栏
    let s2 = new DOM.Splitter();
    s2.SetSplitPosBottom(200);
    s1._panel1.AddChild(s2);
    s2.Style_Fill();



    {
        let sa = new DOM.Splitter();
        sa.SetSplitPosTop(24);
        s2._panel1.AddChild(sa);

        let toolbox = new DOM.Group();
        toolbox.SetTitle("动画");
        _anipanel = toolbox._panel;
        _anipanel.UseScrollV();
        //toolbox._root.style.backgroundColor = "#33c";
        sa._panel2.AddChild(toolbox);

        let btn = new DOM.Button("重加载");
        btn.SetClickEvent(async () => {
            __InitPlayer();
        });
        let btn2 = new DOM.Button("保存");
        sa._panel1.AddChild(btn);
        //sa._panel1.AddChild(btn2);
    }

    {
        let toolbox = new DOM.Group();
        toolbox.SetTitle("方向");
        _dirpanel = toolbox._panel;
        //toolbox._root.style.backgroundColor = "#33c";
        s2._panel2.AddChild(toolbox);
    }

    let sr = DOM.DomTool.AddSpliter();
    sr.SetSplitPosRight(200);
    s1._panel2.AddChild(sr);

    //中栏
    let sc = new DOM.Splitter();
    sc.SetSplitPosBottom(24);
    sr._panel1.AddChild(sc);
    sc.Style_Fill();
    {
        let toolbox = new DOM.Group();
        toolbox.SetTitle("预览");
        //toolbox._root.style.backgroundColor = "#33c";
        sc._panel1.AddChild(toolbox);
        let c = _canvas = new DOM.CanvasRaw();
        toolbox._panel.AddChild(c);
        c.Style_Fill();
        c.getRoot().style.backgroundColor = "#000";

        let btn = new DOM.Button("Play", () => {
            _play = true;
            _pickframe = -1;
            SetFrameUI();
        });
        sc._panel2.AddChild(btn);
        let btn2 = new DOM.Button("Stop", () => {
            _play = false;
        });
        sc._panel2.AddChild(btn2);
        let btn3 = new DOM.Button("|<", () => {
            _play = false;
            if (player != null) {
                SelectFrame(0);
            }
        });
        sc._panel2.AddChild(btn3);
        let btn4 = new DOM.Button("<", () => {
            _play = false;

            if (player != null) {
                SelectFrame(player.activeaniframe - 1);

            }
        });
        sc._panel2.AddChild(btn4);
        let btn5 = new DOM.Button(">", () => {
            _play = false;
            if (player != null) {
                SelectFrame(player.activeaniframe + 1);
            }
        });
        sc._panel2.AddChild(btn5);
        let btn6 = new DOM.Button(">|", () => {
            _play = false;
            if (player != null) {
                SelectFrame(Number.MAX_SAFE_INTEGER);
            }
        });
        sc._panel2.AddChild(btn6);


        let l = new DOM.Space();
       
        sc._panel2.AddChild(l);
        let zbtn1 = new DOM.Button("X1", () => {
            batcher.Scale = 1.0;
        });
        sc._panel2.AddChild(zbtn1);
        let zbtn2 = new DOM.Button("X2", () => {
            batcher.Scale = 2.0;
        });
        sc._panel2.AddChild(zbtn2);
        let zbtn4 = new DOM.Button("X4", () => {
            batcher.Scale = 4.0;
        });
        sc._panel2.AddChild(zbtn4);
    }


    // //右边栏
    // let s3 = new DOM.Splitter();
    // s3.SetSplitPosTop(600);
    // sr._panel2.AddChild(s3);
    // s3.Style_Fill();

    {
        let toolbox = new DOM.Group();
        toolbox.SetTitle("属性");
        _infopanel = toolbox._panel;
        _infopanel.UseScrollV();
        //toolbox._root.style.backgroundColor = "#33c";
        sr._panel2.AddChild(toolbox);
    }


    //底栏
    {
        let toolbox = new DOM.Group();
        toolbox.SetTitle("帧");
        //toolbox._root.style.backgroundColor = "#33c";
        _framepanel = toolbox._panel;
        _framepanel.UseScrollH();
        sbot._panel1.AddChild(toolbox);
    }

    {
        let toolbox = new DOM.Group();
        _debugpanel = toolbox._panel;
        toolbox.SetTitle("信息");
        //toolbox._root.style.backgroundColor = "#33c";
        sbot._panel2.AddChild(toolbox);
    }
}
function Log(txt: string) {
    console.warn(txt);
    _debugpanel.AddChild(new DOM.Label(txt));
}
var batcher: tt.IBatcher;
var player: tt2.QAni2_Player<any>;
var _play: boolean = true;
async function __InitPlayer() {

    _debugpanel.RemoveAllChild();
    _anipanel.RemoveAllChild();


    let file = IO.GetEditFileName();


    try {
        let p = await tt2.QAni2_PlayerMgr.LoadPlayerInfo(file, true);
        Log("load:" + p.playername);
        player = tt2.QAni2_PlayerMgr.CreatePlayer(p.playername);
        if (_pickani == undefined) {
            _pickani = player.aniname;
            _pickdir = player.direction.getDirIndex();
        }
        else {
            player.direction.setDirIndex(_pickdir);
            player.Play(_pickani);
            player.Update(0);
        }
        player.showrect = true;
        SetAniUI();
        SetDirUI();
        SetFrameUI();
        pickAni(_pickani, 0);
    }
    catch (e) {
        Log(e.toString());
        throw e;
    }
}
function SetAniUI() {
    let pickButton: DOM.LabelButton = null;

    //for (var i = 0; i < 50; i++) 
    {
        for (var key in player.data.animations) {
            let btn = new DOM.LabelButton(key);
            _anipanel.AddChild(btn);
            let aname = key;
            if (aname == _pickani) {
                btn.colorBack = new Color32(128, 128, 0, 255);
                btn.colorLabel = new Color32(0, 0, 128, 255);
                btn.UpdateColor();
                pickButton = btn;
            }
            btn.onClick = () => {
                if (pickButton == btn) {
                    return;
                }
                if (pickButton != null) {
                    pickButton.colorBack = new Color32(0, 0, 0, 0);
                    pickButton.colorLabel = new Color32(0, 0, 0, 255);
                    pickButton.UpdateColor();
                }
                pickButton = btn;


                pickButton.colorBack = new Color32(128, 128, 0, 255);
                pickButton.colorLabel = new Color32(0, 0, 128, 255);
                pickButton.UpdateColor();
                pickAni(aname, _pickdir);
            }
        }
    }
}
function SetDirUI() {
    let pickButton: DOM.LabelButton = null;
    if (_dirpanel.GetChildCount() != player.direction.getDirCount()) {
        _dirpanel.RemoveAllChild();
        for (let i = 0; i < player.direction.getDirCount(); i++) {
            let dir = new tt2.QAni2_Direction(player.direction.getDirCount(), i);
            dir.setDirIndex(i);
            let dname = dir.getDirName();
            let btn = new DOM.LabelButton(dname);
            _dirpanel.AddChild(btn);
            if (i == _pickdir) {
                btn.colorBack = new Color32(128, 128, 0, 255);
                btn.colorLabel = new Color32(0, 0, 128, 255);
                btn.UpdateColor();
                pickButton = btn;
            }
            btn.onClick = () => {
                if (pickButton == btn) {
                    return;
                }
                if (pickButton != null) {
                    pickButton.colorBack = new Color32(0, 0, 0, 0);
                    pickButton.colorLabel = new Color32(0, 0, 0, 255);
                    pickButton.UpdateColor();
                }
                pickButton = btn;

                pickAni(_pickani, dir.getDirIndex());

                //player.direction.setDirIndex(dir.getDirIndex());    
                pickButton.colorBack = new Color32(128, 128, 0, 255);
                pickButton.colorLabel = new Color32(0, 0, 128, 255);
                pickButton.UpdateColor();
            }
        }
    }
}
function SelectFrame(frame: number) {
    if (frame < 0)
        frame = 0;
    if (frame > player.activeani.ani.framecount)
        frame = player.activeani.ani.framecount - 1;
    if (_pickframe >= 0) {
        let b = _framepanel.GetChild(_pickframe) as DOM.LabelButton;
        b.colorBack = new Color32(0, 0, 0, 0);
        b.UpdateColor();
    }
    _pickframe = frame;
    if (player != null)
        player.SetFrame(_pickframe);
    _play = false;

    let b = _framepanel.GetChild(_pickframe) as DOM.LabelButton;
    b.colorBack = new Color32(128, 128, 0);
    b.UpdateColor();

    SetInfoUI();
}
function SetFrameUI() {

    _framepanel.RemoveAllChild();
    _framepanel._root.style.display = "block";
    _framepanel._root.style.overflowX = "scroll";
    _framepanel._root.style.overflowY = "hidden";
    _framepanel._root.style.whiteSpace = "nowrap";

    for (var i = 0; i < player.activeani.ani.frames.length; i++) {
        let f = player.activeani.ani.frames[i];
        let key = true;
        if (i > 0) {
            let flast = player.activeani.ani.frames[i - 1];
            if (f == flast) {
                key = false;
            }
        }
        let l = new DOM.LabelButton();
        l._root.style.width = "32px";
        l._root.style.height = "100%";
        l._root.style.display = "inline-block"
        l._root.style.position = "relative";
        l._root.style.border = "1px solid #000";
        l._root.style.verticalAlign = "top";
        l._root.style.textAlign = "center";
        let _frame = i;
        l.onClick = () => {
            SelectFrame(_frame);
        }
        _framepanel.AddChild(l);
        let lid = new DOM.Label(i.toString());
        l.AddChild(lid);
        let lkey = new DOM.Label(key ? "K" : " ");
        lkey._root.style.border = "1px solid #000";
        lkey._root.style.backgroundColor = " #ddd";
        lkey._root.style.color = "000";
        lkey._root.style.width = "30px";
        lkey._root.style.height = "24px";
        l.AddChild(lkey);

        if (key) {
            //精灵标记
            for (var is = 0; is < f.sprites.length; is++) {
                let ls = new DOM.Label("S");
                ls._root.style.color = "#ff0";
                ls._root.style.border = "1px solid #ff0";
                ls._root.style.backgroundColor = "#888";
                ls._root.style.width = "30px";
                ls._root.style.height = "24px";
                l.AddChild(ls);
            }
            //Rect标记
            for (var ir = 0; ir < f.rects.length; ir++) {
                let ls = new DOM.Label("R");

                let color = "";
                if (f.rects[ir].type == tt2.HitType.Attack)
                    color = "#f00";
                if (f.rects[ir].type == tt2.HitType.BeHit)
                    color = "#0f0";
                if (f.rects[ir].type == tt2.HitType.Other)
                    color = "#00f";
                ls._root.style.color = color;
                ls._root.style.border = "1px solid " + color;
                ls._root.style.backgroundColor = "#000";
                ls._root.style.width = "30px";
                ls._root.style.height = "24px";
                l.AddChild(ls);
            }
        }
    }
}
var _pickani: string;
var _pickdir: number = 0;
var _pickframe: number = -1;
async function pickAni(name: string, dirindex: number) {
    _pickani = name;
    _pickdir = dirindex;
    SetDirUI();
    let a = player.data.animations[_pickani];
    player.direction.setDirCount(a.dircount);
    player.direction.setDirIndex(_pickdir);
    player.UpdateAni();
    SetFrameUI();

    SetInfoUI();
}
function SetInfoUI() {
    _infopanel.RemoveAllChild();
    _infopanel.AddChild(new DOM.Label("====Pick Animation: " + name));
    let a = player.data.animations[_pickani];
    _infopanel.AddChild(new DOM.Label("dircount: " + a.dircount));
    _infopanel.AddChild(new DOM.Label("framecount: " + a.framecount));
    _infopanel.AddChild(new DOM.Label("loop: " + a.loop));

    _infopanel.AddChild(new DOM.Label("====dir: " + player.direction.getDirName()));

    _infopanel.AddChild(new DOM.Label("srcname: " + player.activeani.srcname));
    _infopanel.AddChild(new DOM.Label("flipx: " + player.activeani.flipx));
    _infopanel.AddChild(new DOM.Label("flipy: " + player.activeani.flipy));

    if (_pickframe >= 0) {
        _infopanel.AddChild(new DOM.Label("====frame: " + _pickframe));
        let f = a.dirani[_pickdir].ani.frames[_pickframe];

        _infopanel.AddChild(new DOM.Label("当前帧精灵数量:" + f.sprites.length));
        for (var i = 0; i < f.sprites.length; i++) {
            let fs = f.sprites[i];
            _infopanel.AddChild(new DOM.Label("sprite[" + i + "]: " + fs.srcname));
            _infopanel.AddChild(new DOM.Label("  --offset: " + fs.OffsetX + "," + fs.OffsetY));
            _infopanel.AddChild(new DOM.Label("  --scale: " + fs.ScaleX + "," + fs.ScaleY));
        }
        _infopanel.AddChild(new DOM.Label("当前帧rect数量: " + f.rects.length));
        for (var i = 0; i < f.rects.length; i++) {

            let fr = f.rects[i];
            _infopanel.AddChild(new DOM.Label("rect[" + i + "]: " + tt2.HitType[fr.type].toString()));
            _infopanel.AddChild(new DOM.Label("  --: (" + fr.x1 + "," + fr.y1 + " - " + fr.x2 + "," + fr.y2 + ")"));
        }
    }
}